﻿using System.IO;
using System;
using System.Reflection;
using System.Windows;

namespace DeleteAll
{
    class Program
    {
        #region declarations
        static TextWriter _twLogFile = null;
        static String _strLogFile = "";
        static String _strDeleteDir = "";
        static Boolean _fDirectoryExists = false;
        static Boolean _fLogToConsole = true;
        static Boolean _fLogToFile = true;
        static Boolean _fLogOnlyErrors = true;
        #endregion



        #region main functions
        static void Main(string[] args)
        {
            //Get log file name
            _strLogFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DeleteLog.txt";
          
            Boolean _fCreateMenu = true;

            while (_fCreateMenu)
            {
                _fCreateMenu = _createMenu();
            }
        }

        /// <summary>_createMenu</summary>
        /// <returns></returns>
        /// <history>10.09.2011</history>
        static Boolean _createMenu()
        {
            //Prepare refresh
            Boolean fMenuRefresh = true;

            //Create menu
            _drawMenu();
            
            //Read user input
            ConsoleKeyInfo _ckiUserInput = Console.ReadKey(true);

            //Check user input
            switch (_ckiUserInput.Key)
            {
                case ConsoleKey.E://Enter directory
                    Console.Write("Enter directory to delete: ");
                    _strDeleteDir = Console.ReadLine();
                    _fDirectoryExists = Directory.Exists(_strDeleteDir);
                    break;

                case ConsoleKey.C://Toggle log to console
                    _fLogToConsole = !_fLogToConsole;
                    break;

                case ConsoleKey.F://Toggle log to file
                    _fLogToFile = !_fLogToFile;
                    break;

                case ConsoleKey.O://Toggle log only errors
                    _fLogOnlyErrors = !_fLogOnlyErrors;
                    break;

                case ConsoleKey.D://Start deletion process
                    if (_fDirectoryExists)
                    {
                        fMenuRefresh = _startDeletion();
                    }
                    else
                    {
                        Console.Write("Directory to delete does not exist! (Press any key to continue)");
                        Console.ReadKey(true);
                    }
                    break;

                case ConsoleKey.X://User chose Exit
                case ConsoleKey.Escape://User chose Exit
                    fMenuRefresh = false;
                    break;
            }
            
            //Close function
            return fMenuRefresh;
        }

        /// <summary>_startDeletion</summary>
        /// <returns></returns>
        /// <history>10.09.2011</history>
        private static Boolean _startDeletion()
        {
            Boolean fMenuRefresh = true;

            String strFormat = "Do you really want to delete '{0,-1}' recursively? (Y/N)";
            Console.Write(strFormat, _strDeleteDir);
            
            if (Console.ReadKey(true).Key == ConsoleKey.Y)
            {
                //fMenuRefresh = false;

                Console.Clear();
                Console.WriteLine("Starting deletion process !!!");

                if (_fLogToFile)
                {
                    _twLogFile = new StreamWriter(_strLogFile);
                }

                _DeleteFileSystemInfo(new DirectoryInfo(_strDeleteDir) as FileSystemInfo);

                if (_fLogToFile &&
                    _twLogFile!=null)
                {
                    _twLogFile.Flush();
                    _twLogFile.Close();
                    _twLogFile = null;
                }
            }

            Console.Write("Done! (Press any key)");
            Console.ReadKey(true);

            return fMenuRefresh;
        }
        #endregion



        #region menu drawing
        /// <summary>_drawMenu</summary>
        /// <history>10.09.2011</history>
        private static void _drawMenu()
        {
            try
            {
                String strFormatText = "{0,-22}{1,-1}";
                String strFormatBool = "[{1,1}] {0,-1}";

                Console.BackgroundColor = ConsoleColor.Blue;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Clear();

                Console.WriteLine("Recursive Deletion Program v1.0");
                Console.WriteLine("");
                Console.WriteLine("Information");
                Console.WriteLine("--------------------------------------------------------------------------");
                //Console.WriteLine("Directory to delete :");
                Console.WriteLine(strFormatText, "Directory to delete :", _strDeleteDir);
                Console.WriteLine(strFormatBool, "Directory exists", _fDirectoryExists ? "X" : " ");
                Console.WriteLine("");
                Console.WriteLine(strFormatBool, "Log to console", _fLogToConsole ? "X" : " ");
                Console.WriteLine(strFormatBool, "Log to file", _fLogToFile ? "X" : " ");
                Console.WriteLine("");
                Console.WriteLine(strFormatBool, "Log only errors", _fLogOnlyErrors ? "X" : " ");
                Console.WriteLine("");
                Console.WriteLine("");
                Console.WriteLine("Main Menu");
                Console.WriteLine("--------------------------------------------------------------------------");
                Console.WriteLine("E - Enter directory to delete");
                Console.WriteLine("C - Toggle \"Log to console\" switch");
                Console.WriteLine("F - Toggle \"Log to file\" switch");
                Console.WriteLine("O - Toggle \"Log only errors\" switch");
                Console.WriteLine("");
                Console.WriteLine("D - Start deletion process");
                Console.WriteLine("");
                Console.WriteLine("X - Exit Program");
                Console.WriteLine("");
            }
            catch(Exception ex)
            {

                throw ex;
            }
        }
        #endregion



        #region deletion functions
        /// <summary>_DeleteFileSystemInfo</summary>
        /// <param name="fsi"></param>
        /// <history>10.09.2011</history>
        private static void _DeleteFileSystemInfo(FileSystemInfo fsi)
        {
            _logFileDirName(fsi.FullName, null);

            try
            {
                fsi.Attributes = FileAttributes.Normal;
                var di = fsi as DirectoryInfo;

                if(di != null)
                {
                    foreach(var dirInfo in di.GetFileSystemInfos())
                    {
                        _DeleteFileSystemInfo(dirInfo);
                    }
                }

                try
                {
                    fsi.Delete();
                }
                catch(Exception ex)
                {
                    _logFileDirName(fsi.FullName, ex);
                }
            }
            catch(Exception ex)
            {
                _logFileDirName(fsi.FullName, ex);
            }
        }

        /// <summary>_logFileDirName</summary>
        /// <param name="strFileDirName"></param>
        /// <history>11.09.2011</history>
        private static void _logFileDirName(
            String strFileDirName,
            Exception ex)
        {
            if(!(_fLogOnlyErrors && ex == null))
            {
                //prepare log line
                String strFormat = "";

                //create log line frame
                if(ex == null)
                {
                    strFormat = "Deleting '{0,-1}'";
                }
                else
                {
                    strFormat = "Error deleting '{0,-1}'! (exception message: {1,-1})";
                }

                //write log line to console
                if(_fLogToConsole)
                {
                    if(ex == null)
                    {
                        Console.WriteLine(strFormat, strFileDirName);
                    }
                    else
                    {
                        Console.WriteLine(strFormat, strFileDirName, ex.Message);
                    }
                }

                //write log line to file
                if(_fLogToFile)
                {
                    if(ex == null)
                    {
                        _twLogFile.WriteLine(strFormat, strFileDirName);
                    }
                    else
                    {
                        _twLogFile.WriteLine(strFormat, strFileDirName, ex.Message);
                    }
                }
            }
        }
        #endregion
    }
}
